package com.springboot.frame.mapper;

import com.springboot.frame.Condition;
import com.springboot.frame.mapper.provider.DeleteMapperProvider;
import com.springboot.frame.mapper.provider.SelectMapperProvider;
import com.springboot.frame.mapper.provider.UpdateMapperProvider;
import org.apache.ibatis.annotations.*;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * 公共Mapper
 *
 * @author liheng
 */
public interface BaseMapper<T extends Serializable, PKID extends Serializable> {

  /**
   * 通过主键查询单结果
   *
   * @param id 主键ID
   * @return 单个结果
   */
  @SelectProvider(type = SelectMapperProvider.class, method = "selectById")
  T selectById(PKID id);

  /**
   * 通过主键集合查询多个结果
   *
   * @param ids 主键集合
   * @return 多个结果
   */
  @SelectProvider(type = SelectMapperProvider.class, method = "selectBatchIds")
  List<T> selectBatchIds(Collection<PKID> ids);

  /**
   * 通过条件对象查询数据量
   *
   * @param condition 条件对象
   * @return 数据量
   */
  @SelectProvider(type = SelectMapperProvider.class, method = "selectCount")
  PKID selectCount(Condition<T> condition);

  /**
   * 通过条件对象查询单结果
   *
   * @param condition 条件对象
   * @return 单个结果
   */
  @SelectProvider(type = SelectMapperProvider.class, method = "selectList")
  T selectOnly(Condition<T> condition);

  /**
   * 通过条件对象查询多个结果
   *
   * @param condition 条件对象
   * @return 多个结果
   */
  @SelectProvider(type = SelectMapperProvider.class, method = "selectList")
  List<T> selectList(Condition<T> condition);

  /**
   * 通过主键删除单对象
   *
   * @param id 主键
   * @return 是否删除成功
   */
  @DeleteProvider(type = DeleteMapperProvider.class, method = "deleteById")
  boolean deleteById(PKID id);

  /**
   * 通过条件对象删除
   *
   * @param condition 条件对象
   * @return 是否删除成功
   */
  @DeleteProvider(type = DeleteMapperProvider.class, method = "delete")
  boolean delete(Condition<T> condition);

  /**
   * 通过主键集合删除
   *
   * @param ids 主键集合
   * @return 是否删除成功
   */
  @DeleteProvider(type = DeleteMapperProvider.class, method = "deleteBatchIds")
  boolean deleteBatchIds(Collection<PKID> ids);

  /**
   * 清空表
   * @return
   */
  @DeleteProvider(type = DeleteMapperProvider.class, method = "truncateTable")
  boolean truncateTable();

  /**
   * 选择性插入一个对象
   *
   * @param t 待插入对象
   * @return 是否插入成功
   */
  @InsertProvider(type = UpdateMapperProvider.class, method = "insert")
  @Options(useGeneratedKeys = true,keyProperty = "id",keyColumn = "id")
  boolean insert(T t);

  /**
   * 全可插入字段插入一个对象
   *
   * @param t 待插入对象
   * @return 是否插入成功
   */
  @InsertProvider(type = UpdateMapperProvider.class, method = "insertAllColumns")
  @Options(useGeneratedKeys = true,keyProperty = "id",keyColumn = "id")
  boolean insertAllColumns(T t);

  /**
   * 通过主键更新对象
   *
   * @param t 需要更新的对象,需带主键
   * @return 是否更新成功
   */
  @UpdateProvider(type = UpdateMapperProvider.class, method = "updateById")
  boolean updateById(T t);

  /**
   * 全可更新字段通过主键更新对象
   *
   * @param t 需要更新的对象,需带主键
   * @return 是否更新成功
   */
  @UpdateProvider(type = UpdateMapperProvider.class, method = "updateAllColumnsById")
  boolean updateAllColumnsById(T t);

  /**
   * 通过条件对象选择性更新对象
   *
   * @param condition 条件对象
   * @return 是否更新成功
   */
  @UpdateProvider(type = UpdateMapperProvider.class, method = "update")
  boolean update(Condition condition);

  /**
   * 全可更新字段通过条件更新对象
   *
   * @param condition 条件对象
   * @return 是否更新成功
   */
  @UpdateProvider(type = UpdateMapperProvider.class, method = "updateAllColumns")
  boolean updateAllColumns(Condition<T> condition);

  /**
   * 根据主键Id,选择性保存或者更新对象
   *
   * @param t 需要保存或更新的对象
   * @return 是否保存或更新成功
   */
  @InsertProvider(type = UpdateMapperProvider.class, method = "saveOrUpdate")
  boolean saveOrUpdate(T t);

  /**
   * 全可更新或插入字段根据主键Id,保存或者更新对象
   *
   * @param t 需要保存或更新的对象
   * @return 是否保存或更新成功
   */
  @InsertProvider(type = UpdateMapperProvider.class, method = "saveOrUpdateAllColumns")
  boolean saveOrUpdateAllColumns(T t);

}
